package cn.zlp.hrm.service.impl;

import cn.zlp.hrm.ai.service.IAIContentAuditService;
import cn.zlp.hrm.client.CourseDocClient;
import cn.zlp.hrm.config.RabbitMQConfig;
import cn.zlp.hrm.doc.CourseDoc;
import cn.zlp.hrm.domain.*;
import cn.zlp.hrm.dto.CourseDto;
import cn.zlp.hrm.enums.CourseGrade;
import cn.zlp.hrm.exception.ErrorCode;
import cn.zlp.hrm.exception.ValidUtils;
import cn.zlp.hrm.holder.UserContextInfoHolder;
import cn.zlp.hrm.mapper.*;
import cn.zlp.hrm.query.CourseQuery;
import cn.zlp.hrm.service.ICourseService;
import cn.zlp.hrm.util.AjaxResult;
import cn.zlp.hrm.util.PageList;
import cn.zlp.hrm.vo.UserContextInfo;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zlp
 * @since 2022-01-08
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private CourseDetailMapper courseDetailMapper;

    @Autowired
    private CourseMarketMapper courseMarketMapper;

    @Autowired
    private CourseAuditLogMapper courseAuditLogMapper;

    @Autowired
    private IAIContentAuditService aiContentAuditService;

    @Autowired
    private CourseOnlineLogMapper courseOnlineLogMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 分页查询
     * @param query
     * @return
     */
    @Override
    public PageList<Course> selectPageList(CourseQuery query) {
        Page<Course> page = new Page<>(query.getPage(),query.getRows());
        List<Course> datas =  courseMapper.loadPageList(page,query);
        return new PageList<>(page.getTotal(),datas);
    }

    /**
     * 课程修改
     * @param courseDto
     */
    @Override
    public void updateById(CourseDto courseDto) {
        Course course = courseDto.getCourse();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        // 校验
        // 1.1 适用jsr303完成null校验
        // 1.2 对课程等级进行合法性校验
        CourseGrade grade = CourseGrade.getGrade(course.getGradeId());
        ValidUtils.assertNotNull(grade, ErrorCode.CODE_400_COURSE_GRADE_ILLEGAL);
        String content = course.getName()+" "+ course.getForUser()+" "+ courseDetail.getIntro()+" "+ courseDetail.getDescription();
        AjaxResult ajaxResult = aiContentAuditService.audit(content, null, null);
        // 自动审核是否通过
        int status = ajaxResult.isSuccess() ? 1 : 0;
        course.setStatus(status);
        // 修改课程
        courseMapper.updateById(course);
        // 修改课程市场分析
        courseMarketMapper.updateById(courseMarket);
        // 修改课程明细
        courseDetailMapper.updateById(courseDetail);
        // 百度人工智能审核
        auditHandle(ajaxResult.getMessage(),course);
    }

    /**
     * 课程添加
     * @param courseDto
     */
    @Override
    public void insert(CourseDto courseDto) {
        Course course = courseDto.getCourse();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        // 校验
        // 1.1 适用jsr303完成null校验
        // 1.2 对课程等级进行合法性校验
        CourseGrade grade = CourseGrade.getGrade(course.getGradeId());
        ValidUtils.assertNotNull(grade, ErrorCode.CODE_400_COURSE_GRADE_ILLEGAL);
        String content = course.getName()+" "+ course.getForUser()+" "+ courseDetail.getIntro()+" "+ courseDetail.getDescription();
        AjaxResult ajaxResult = aiContentAuditService.audit(content, null, null);
        // 自动审核是否通过
        int status = ajaxResult.isSuccess() ? 1 : 0;
        course.setStatus(status);
        // 添加课程
        courseMapper.insert(course);
        // 添加课程市场分析
        Long courseId = course.getId();
        courseMarket.setId(courseId);
        courseMarketMapper.insert(courseMarket);
        // 添加课程明细
        courseDetail.setId(courseId);
        courseDetailMapper.insert(courseDetail);
        // 百度人工智能审核
        auditHandle(ajaxResult.getMessage(),course);
    }

    @Autowired
    private CourseDocClient courseDocClient;

    @Autowired
    private CourseTypeMapper courseTypeMapper;

    /**
     * 课程上线
     * @param ids
     * @return
     */
    @Override
    public AjaxResult online(List<Long> ids) {
        // 1.校验
        ValidUtils.assertListNotNull(ids,ErrorCode.CODE_400_COURSE_GRADE_ILLEGAL);
        // 2.数据库修改状态
        courseMapper.online(ids);
        // 声明用来装生成的集合
        List<CourseDoc> docs = new ArrayList<>();
        List<CourseOnlineLog> courseOnlineLogs  = new ArrayList<>();
        // 因为遍历两次,所以用普通遍历合在一起,提高效率
        for (Long id : ids) {
            // 根据id查询课程
            Course course = courseMapper.selectById(id);
            CourseDoc doc = new CourseDoc();
            // 拷贝相同属性到文档
            BeanUtils.copyProperties(course,doc);
            // 设置课程类型
            CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
            doc.setCourseTypeName(courseType.getName());
            // 设置市场信息
            CourseMarket courseMarket = courseMarketMapper.selectById(id);
            BeanUtils.copyProperties(courseMarket,doc);
            // 将生成的文档添加到集合中
            docs.add(doc);
            // 生成上架日志
            CourseOnlineLog log = course2OnlineLog(course);
            courseOnlineLogs.add(log);
        }
        // 3.调用feigin接口,批量添加CourseDoc到es中保存
        courseDocClient.batchAdd(docs);
        // 4.保存上下架日志
        courseOnlineLogMapper.batchSave(courseOnlineLogs);
        // 5.模拟推送信息
        publishMessage(ids);
        return AjaxResult.me();
    }

    /**
     * 上架日志
     * @param course
     * @return
     */
    private CourseOnlineLog course2OnlineLog(Course course) {
        UserContextInfo userContextInfo = UserContextInfoHolder
                .getUserContextInfo();
        System.out.println(userContextInfo);
        CourseOnlineLog log = new CourseOnlineLog();
        log.setCourseId(course.getId());
        log.setCourseName(course.getName());
        log.setOprAdminId(userContextInfo.getEmployeeId());
        log.setOprAdminName(userContextInfo.getEmpUsername());
        log.setState(1);
        log.setOnlineTime(new Date());
        return log;
    }

    private void publishMessage(List<Long> ids) {
        // 5.1短信推送
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME_TOPIC,"message.sms",ids);
        // 5.2email推送
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME_TOPIC,"message.email",ids);
        // 5.3组内消息推送
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME_TOPIC,"message.system",ids);
    }

    /**
     * 下线
     * @param ids
     * @return
     */
    @Override
    public AjaxResult offline(List<Long> ids) {
        // 校验
        ValidUtils.assertListNotNull(ids,ErrorCode.CODE_400_COURSE_GRADE_ILLEGAL);
        // 数据库修改状态
        courseMapper.offline(ids);
        // 调用feigin接口,在es中删除
        courseDocClient.batchDel(ids);
        // 保存上下架日志
        batchOffLineLog(ids);
        return AjaxResult.me();
    }

    /**
     * 批量添加下架日志
     * @param ids
     */
    private void batchOffLineLog(List<Long> ids) {
        List<CourseOnlineLog> courseOnlineLogs = ids.stream().map(id -> {
            Course course = courseMapper.selectById(id);
            CourseOnlineLog log = new CourseOnlineLog();
            log.setCourseId(course.getId());
            log.setCourseName(course.getName());
            log.setState(0);
            log.setOfflineTime(new Date());
            return log;
        }).collect(Collectors.toList());
        courseOnlineLogMapper.batchSave(courseOnlineLogs);
    }

    @Override
    public boolean deleteById(Serializable courseId) {
        courseMapper.deleteById(courseId);
        courseMarketMapper.deleteById(courseId);
        courseDetailMapper.deleteById(courseId);
        return true;
    }

    /**
     * 审核处理
     * @param message
     * @param course
     */
    private void auditHandle(String message, Course course) {
        CourseAuditLog auditLog = course2CourseAuditLog(message,course);
        courseAuditLogMapper.insert(auditLog);
    }

    private CourseAuditLog course2CourseAuditLog(String message, Course course) {
        CourseAuditLog auditLog = new CourseAuditLog();
        auditLog.setCourseId(course.getId());
        auditLog.setCourseName(course.getName());
        auditLog.setState(course.getStatus());
        String note = course.getStatus()!=-1 ? "审核通过!":message;
        auditLog.setNote(note);
        auditLog.setAuditTime(new Date());
        auditLog.setAuditAdminId(null);
        auditLog.setAuditAdminName("系统自动审核");
        return auditLog;
    }
}
